﻿using System.Data;
using Microsoft.SqlServer.Replication.BusinessLogicSupport;

namespace SqlMyReplicationModule
{
    /// <summary>
    ///  Der Verweis für die "Microsoft.SqlServer.Replication.BusinessLogicSupport.dll" liegt normalerweise unter:  C:\Program Files (x86)\Microsoft SQL Server\100\COM\
    /// </summary>
    public class MyReplicationModule : BusinessLogicModule
    {
        #region Properties
        /// <summary>
        /// Gibt an welche Änderungen von unserem Plugin verarbeitet werden sollen. 
        /// In unserem Falle nur Fehler die beim Einfügen des Subscribers oder Publishers auftreten.
        /// </summary>
        public override ChangeStates HandledChangeStates
        {
            get { return ChangeStates.SubscriberInsertErrors 
                | ChangeStates.PublisherInsertErrors; }
        }

        /// <summary>
        /// beinhaltet alle wichtigen Verbindungsinformationen für die SQL Replikation
        /// </summary>
        public SqlReplicationConnection SqlReplicationConnection { get; set; }
        #endregion

        #region Public functions
        /// <summary>
        /// Initialisieren, damit wir alle wichtigen Informationen erhalten um z.B. eine DB Verbindung öffnen zu können und das Problem zu lösen.
        /// </summary>
        public override void Initialize(string publisher, string subscriber, string distributor, string publisherDb, string subscriberDb, string articleName)
        {
            SqlReplicationConnection = new SqlReplicationConnection(publisher, subscriber, distributor, publisherDb, subscriberDb, articleName);
        }
        #endregion

        #region Override Events
        /// <summary>
        /// Da wir in den HandleChangeStates nur auf InsertError "lauschen" wird nur diese Funktion von uns überschrieben. 
        /// </summary>
        /// <returns></returns>
        public override ActionOnDataError InsertErrorHandler(SourceIdentifier insertSource, DataSet insertedDataSet, ref ErrorLogType errorLogType, ref string customErrorMessage, int errorCode, string errorMessage, ref int historyLogLevel, ref string historyLogMessage)
        {
            //Wenn es sich um die jeweils passende Tabelle handelt, die jeweiligen Aktionen ausführen. Hier wird überprüft ob die Tabelle
            //bei der es zu einem InsertError gekommen ist "Kategorie" heißt, wenn ja kann für diese Tabelle dann der passende Code ausgeführt werden.
            if (SqlReplicationConnection.ArticleName.ToLower() == "Kategorie")
            {
                //Hier die Replikation manipulieren und wenn alles erfolgreich abgelaufen ist, das passende Return liefern.
                string kategorieId = insertedDataSet.Tables[0].Rows[0]["id"].ToString();
                string secondId = insertedDataSet.Tables[0].Rows[0]["secondId"].ToString();
                //Die Abfrage erstellen die auf beiden Systemen durchgeführt werden soll Publisher und Subscriber
                string sqlString = string.Format("Select * from {0} where id = {1} and secondId = {2}", SqlReplicationConnection.ArticleName, kategorieId, secondId);

                //Prüfen ob hier ein Datensatz gefunden werden kann.
                DataTable tablePublisher = SqlReplicationConnection.GetDataTable(sqlString, SqlReplicationConnection.RepType.Publisher);
                //... Weitere Logik z.B. Löschen von Datensätzen oder Manipulieren

                return ActionOnDataError.AcceptCustomErrorBehavior;
            }

            return base.InsertErrorHandler(insertSource, insertedDataSet, ref errorLogType, ref customErrorMessage, errorCode, errorMessage, ref historyLogLevel, ref historyLogMessage);
        }
        #endregion
    }
}
